package com.ibm.maf.rmi;

/*
 * @(#)MAFFinder_RMIImpl.java
 * 
 * IBM Confidential-Restricted
 * 
 * OCO Source Materials
 * 
 * 03L7246 (c) Copyright IBM Corp. 1996, 1998
 * 
 * The source code for this program is not published or otherwise
 * divested of its trade secrets, irrespective of what has been
 * deposited with the U.S. Copyright Office.
 */
import com.ibm.maf.NameInvalid;
import com.ibm.maf.*;
import java.util.*;
import java.rmi.RemoteException;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

public class MAFFinder_RMIImpl extends java.rmi.server.UnicastRemoteObject 
	implements com.ibm.maf.MAFFinder {
	static private boolean _verbose = false;

	static public final String REGISTRY_NAME = "MAFFinder";
	static public final int REGISTRY_PORT = 4435;

	private Hashtable _agent_systems;
	private Hashtable _places;
	private Hashtable _agents;

	public MAFFinder_RMIImpl() throws RemoteException {
		_agent_systems = new Hashtable();
		_places = new Hashtable();
		_agents = new Hashtable();
	}
	public Hashtable list_agent_entries() throws RemoteException {
		return _agents;
	}
	public Hashtable list_agent_system_entries() throws RemoteException {
		return _agent_systems;
	}
	public Hashtable list_place_entries() throws RemoteException {
		return _places;
	}
	public String[] lookup_agent(Name agent_name, AgentProfile agent_profile) 
			throws EntryNotFound, RemoteException {
		VerbosePrintln("lookup_agent: " + agent_name.toString());
		String result[];

		if (agent_name != null) {
			LocationInfo pair = (LocationInfo)_agents.get(agent_name);

			if (pair != null) {
				result = new String[1];
				result[0] = pair.getLocation();
			} else {
				throw new EntryNotFound();
			} 
		} else {
			Vector v = new Vector();

			for (Enumeration e = _agents.elements(); e.hasMoreElements(); ) {
				LocationInfo p = (LocationInfo)e.nextElement();

				if (p.matchAgentProfile(agent_profile)) {
					v.addElement(p.getLocation());
				} 
			} 
			if (v.size() == 0) {
				throw new EntryNotFound();
			} 
			result = new String[v.size()];
			v.copyInto(result);
		} 

		return result;
	}
	public String[] lookup_agent_system(Name agent_system_name, 
										AgentSystemInfo agent_system_info) throws EntryNotFound, 
										RemoteException {
		VerbosePrintln("lookup_agent_system: " 
					   + agent_system_name.toString());
		String result[];

		if (agent_system_name != null) {
			LocationInfo pair = 
				(LocationInfo)_agent_systems.get(agent_system_name);

			if (pair != null) {
				result = new String[1];
				result[0] = pair.getLocation();
				return result;
			} else {
				throw new EntryNotFound();
			} 
		} else {
			Vector v = new Vector();

			for (Enumeration e = _agent_systems.elements(); 
					e.hasMoreElements(); ) {
				LocationInfo p = (LocationInfo)e.nextElement();

				if (p.matchAgentSystemInfo(agent_system_info)) {
					v.addElement(p.getLocation());
				} 
			} 
			if (v.size() == 0) {
				throw new EntryNotFound();
			} 
			result = new String[v.size()];
			v.copyInto(result);
			return result;
		} 
	}
	public String[] lookup_place(String place_name) 
			throws EntryNotFound, RemoteException {
		VerbosePrintln("lookup_place: " + place_name);
		String place = (String)_places.get(place_name);

		if (place == null) {
			throw new EntryNotFound();
		} 
		String[] result = new String[1];

		result[0] = place;
		return result;
	}
	static public void main(String[] args) throws Exception {
		String name = REGISTRY_NAME;
		int port = REGISTRY_PORT;

		if (args.length > 0) {
			for (int i = 0; i < args.length; i++) {
				if (args[i].equalsIgnoreCase("-verbose")) {
					_verbose = true;
				} else if (args[i].equalsIgnoreCase("-help")) {
					usage();
				} else if (i + 1 < args.length) {
					if (args[i].equalsIgnoreCase("-port")) {
						port = Integer.parseInt(args[i + 1]);
						i++;
					} else if (args[i].equalsIgnoreCase("-name")) {
						name = args[i + 1];
						i++;
					} else {
						usage();
					} 
				} else {
					usage();
				} 
			} 
		} 
		MAFFinder_RMIImpl finder = new MAFFinder_RMIImpl();

		finder.startFinder(name, port);

		// Check if this is called from the script generated by InstallShield
		String jshield = System.getProperties().getProperty("install.root");

		if (jshield != null) {
			MAFFinder_InfoFrame f = new MAFFinder_InfoFrame(name, port);

			f.pack();
			f.show();
		} 
	}
	public void register_agent(Name agent_name, String agent_location, 
							   AgentProfile agent_profile) throws NameInvalid, 
							   RemoteException {
		VerbosePrintln("register_agent:");
		VerbosePrintln(" name:\t" + agent_name.toString());
		VerbosePrintln(" location:\t" + agent_location);
		_agents.put(agent_name, 
					new LocationInfo(agent_location, agent_profile));
	}
	public void register_agent_system(Name agent_system_name, 
									  String agent_system_location, 
									  AgentSystemInfo agent_system_info) throws NameInvalid, 
									  RemoteException {
		VerbosePrintln("register_agent_system:");
		VerbosePrintln(" name:\t" + agent_system_name.toString());
		VerbosePrintln(" location:\t" + agent_system_location);
		LocationInfo old_reg = 
			(LocationInfo)_agent_systems.get(agent_system_name);

		if (old_reg != null) {
			throw new NameInvalid();
		} 
		_agent_systems.put(agent_system_name, 
						   new LocationInfo(agent_system_location, 
											agent_system_info));
	}
	public void register_place(String place_name, String place_location) 
			throws NameInvalid, RemoteException {
		VerbosePrintln("register_place:");
		VerbosePrintln(" name:\t" + place_name);
		VerbosePrintln(" location:\t" + place_location);
		String old_place = (String)_places.get(place_name);

		if (old_place != null) {
			throw new NameInvalid();
		} 
		_places.put(place_name, place_location);
	}
	public void startFinder(String name, int port) throws RemoteException {
		Registry reg = LocateRegistry.createRegistry(port);

		reg.rebind(name, this);
		System.out.println("MAFFinder bound in local registry");
		System.out.println("\tname: " + new String(name));
		System.out.println("\tport: " + port);
	}
	public void unregister_agent(Name agent_name) 
			throws EntryNotFound, RemoteException {
		VerbosePrintln("unregister_agent:");
		VerbosePrintln(" name:\t" + agent_name.toString());
		Object o = _agents.remove(agent_name);

		if (o == null) {
			throw new EntryNotFound();
		} 
	}
	public void unregister_agent_system(Name agent_system_name) 
			throws EntryNotFound, RemoteException {
		VerbosePrintln("unregister_agent_system:");
		VerbosePrintln(" name:\t" + agent_system_name.toString());
		Object o = _agent_systems.remove(agent_system_name);

		if (o == null) {
			throw new EntryNotFound();
		} 
	}
	public void unregister_place(String place_name) 
			throws EntryNotFound, RemoteException {
		VerbosePrintln("unregister_place:");
		VerbosePrintln(" name:\t" + place_name);
		Object o = _places.remove(place_name);

		if (o == null) {
			throw new EntryNotFound();
		} 
	}
	static private void usage() {
		System.err
			.println("\nMAFFinder(com.ibm.maf.rmi.MAFFinder_RMIImpl) usage:");
		System.err.print("  options: [-name <name>]  ");
		System.err.println("name to register(default MAFFinder)");
		System.err.print("           [-port <num>]   ");
		System.err.println("registry port(default " + REGISTRY_PORT + ")");
		System.err.print("           [-verbose]      ");
		System.err.println("verbose output");
		System.err.print("           [-help]         ");
		System.err.println("print this message");
		System.exit(1);
	}
	static private void VerbosePrint(String s) {
		if (_verbose) {
			System.err.print(s);
		} 
	}
	static private void VerbosePrintln(String s) {
		if (_verbose) {
			System.err.println(s);
		} 
	}
}
